在完成所有 user 的 API 後,有一些很重要的問題需要留意,有些 method 是只有處於登入狀態,甚至還必須是 admin 的身份才能夠發送該請求。為了能夠驗證是否有使用者登入,我們可以利用 Middleware 的方式過濾掉未登入的使用者。
還記得之前在更改 create_user_table 的時候有添加一個 token 的欄位,而我們驗證登入的方式正是檢驗 Http Header 中有沒有 token 的存在。
首先透過 artisan 建立自己的 middleware:
$ php artisan make:middleware TokenAuth
建立完成後該 middleware 將會存在於 app/Http/Middleware 的資料夾裡頭。
於 app/Http/Kernel.php 檔案裡,註冊該 middleware 於 $routeMiddleware
裡
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
// 註冊的 middleware
'token.auth' => \App\Http\Middleware\TokenAuth::class
];
設計 middleware 的邏輯
此處是以比較土法煉鋼的方式驗證使用者,其實還有更快的方式( 用內建的 Auth::user(),但不知為何自己總是嘗試失敗... )
*app/Http/Middleware/TokenAuth.php
<?php
namespace App\Http\Middleware;
use Closure;
use App\User;
class TokenAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// 確認 Http Header 的 token 有無對應的使用者
$api_token = request()->header('api_token');
$auth_user = User::where('api_token', $api_token)->get();
if(!count($auth_user)){
return response(['message' => 'Authentication error']);
}
// 將通過驗證的使用者存放於 attribute 裡以便將變數傳給 controller
$request->attributes->set('auth_user', $auth_user);
return $next($request);
}
}
定義權限
以下權限的定義並非所謂的正確答案,可以視情況調整
method | admin | regular user | Unauthenticated user |
---|
register|-|-|O
login|-|-|O
index|O|X|X
show|O|只有自己|X
update|只有自己|只有自己|X
delete|O|只有自己|X
說明:
register 和 login 的情形不會將已登入的使用者考慮在內
index 只有 admin 才可以查看所有使用者資料
show、delete 除了 admin 之外,只有該資料為自己的時候請求才能夠被執行
update 則是無論是否為 admin 都只有自己能夠更改資料
API routes 引用 middleware
在 router 引用 middleware 的語法有很多種,以下取其中兩種
*routes/api.php
一、
Route::post('register', 'UsersController@store');
Route::post('login', 'UsersController@login');
Route::get('users', 'UsersController@index')->middleware('token.auth');
Route::get('users/{id}', 'UsersController@show')->middleware('token.auth');
Route::put('users/{id}', 'UsersController@update')->middleware('token.auth');
Route::delete('users/{id}', 'UsersController@destroy')->middleware('token.auth');
二、
Route::group(['middleware' => ['token.auth']], function () {
Route::get('user', 'UsersController@index');
Route::get('user/{id}', 'UsersController@show');
Route::put('user/{id}', 'UsersController@update');
Route::delete('user/{id}', 'UsersController@destroy');
});
Route::group(['middleware' => ['']], function () {
Route::post('register', 'UsersController@store');
Route::post('login', 'UsersController@login');
});
以 register 和 index 為例子
register
不需要使用者登入 ( header 未含任何參數 ) 就可以採用的 method
index
必須經過使用者登入才可以採用 ( admin 的權限部份下一篇會解釋如何實作,此處先檢測使否登入 )
下一篇接續此篇主題,探討經由 middleware 過濾後的使用者後續處理。
參考資料: